<template>
  <div class="channel-tree-v2">
    <div class="tree-header">
      <span class="tree-title">通道列表</span>
      <div class="tree-actions">
        <el-button size="small" @click="expandAll">展开全部</el-button>
        <el-button size="small" @click="collapseAll">收起全部</el-button>
      </div>
    </div>
    
    <el-tree-v2
      ref="treeRef"
      :data="filteredTreeData"
      :props="treeProps"
      :height="400"
      :default-expanded-keys="defaultExpandedKeys"
      :default-checked-keys="defaultCheckedKeys"
      show-checkbox
      node-key="id"
      class="channel-tree"
      @check="handleCheck"
      @node-click="handleNodeClick"
    >
      <template #default="{ data }">
        <div class="tree-node">
          <el-icon v-if="data.type === 'group'" class="node-icon group-icon">
            <Folder />
          </el-icon>
          <el-icon v-else class="node-icon camera-icon">
            <VideoCamera />
          </el-icon>
          
          <span class="node-label" v-html="highlightText(data.label, props.searchKeyword)"></span>
          
          <div v-if="data.type === 'camera'" class="node-info">
            <el-tag 
              :type="getStatusTagType(data.data?.status)" 
              size="small"
              class="status-tag"
            >
              {{ getStatusText(data.data?.status) }}
            </el-tag>
            
            <!-- 播放按钮或占位空间 -->
            <el-button
              v-if="data.data?.status === 'online'"
              size="small"
              type="primary"
              :icon="VideoPlay"
              circle
              class="play-button"
              @click.stop="handlePlayClick(data)"
            />
            <div v-else class="play-button-placeholder"></div>
            
            <!-- IP信息 -->
            <el-tooltip 
              v-if="data.data?.ip" 
              :content="data.data.ip" 
              placement="top"
              :disabled="!isIpTruncated(data.data.ip)"
            >
              <span class="ip-info">{{ data.data.ip }}</span>
            </el-tooltip>
          </div>
        </div>
      </template>
    </el-tree-v2>
    
    <!-- 视频播放对话框 -->
    <StreamPlayerDialog
      v-model:visible="streamPlayerVisible"
      :camera-data="selectedCameraData"
      :server-data="selectedServerData"
      @close="handleStreamPlayerClose"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { ElTreeV2, ElButton, ElIcon, ElTag, ElTooltip } from 'element-plus'
import { Folder, VideoCamera, VideoPlay } from '@element-plus/icons-vue'
import { fetchCameraTree, loadDevicesForTree } from '@/utils/cameraTree'
import { buildStreamUrl } from '@/utils/streamUrl'
import { useStreamStore } from '@/stores/stream'
import StreamPlayerDialog from '@/views/device/stream/components/StreamPlayerDialog.vue'
import type { ChannelTreeNode, Device, StreamServer } from '@/types'

// Props
interface Props {
  modelValue?: string[] // 选中的节点ID数组
  showCheckbox?: boolean
  height?: number
  searchKeyword?: string // 搜索关键词
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => [],
  showCheckbox: true,
  height: 400,
  searchKeyword: ''
})

// Emits
const emit = defineEmits<{
  'update:modelValue': [value: string[]]
  'check': [checkedKeys: string[], checkedNodes: any[]]
  'node-click': [data: any]
}>()

// Store实例
const streamStore = useStreamStore()

// 响应式数据
const treeRef = ref()
const treeData = ref<ChannelTreeNode[]>([])
const filteredTreeData = ref<ChannelTreeNode[]>([])
const loading = ref(false)
const defaultExpandedKeys = ref<string[]>([])
const defaultCheckedKeys = ref<string[]>([])

// 播放相关数据
const streamPlayerVisible = ref(false)
const selectedCameraData = ref<Device | null>(null)
const selectedServerData = ref<StreamServer | null>(null)

// Tree V2 配置
const treeProps = {
  children: 'children',
  label: 'label',
  disabled: 'disabled',
  isLeaf: 'isLeaf'
}

// 计算属性 - 移除未使用的checkedKeys

// 方法
const getStatusTagType = (status?: string) => {
  switch (status) {
    case 'online': return 'success'
    case 'offline': return 'info'
    case 'error': return 'danger'
    default: return 'info'
  }
}

const getStatusText = (status?: string) => {
  switch (status) {
    case 'online': return '在线'
    case 'offline': return '离线'
    case 'error': return '错误'
    default: return '未知'
  }
}

const expandAll = () => {
  const allKeys = getAllNodeKeys(filteredTreeData.value)
  defaultExpandedKeys.value = allKeys
}

const collapseAll = () => {
  defaultExpandedKeys.value = []
}

const getAllNodeKeys = (nodes: ChannelTreeNode[]): string[] => {
  const keys: string[] = []
  const traverse = (nodeList: ChannelTreeNode[]) => {
    nodeList.forEach(node => {
      keys.push(node.id)
      if (node.children) {
        traverse(node.children)
      }
    })
  }
  traverse(nodes)
  return keys
}

// 搜索过滤方法
const filterTreeData = (nodes: ChannelTreeNode[], keyword: string): ChannelTreeNode[] => {
  if (!keyword.trim()) {
    return nodes
  }
  
  const filtered: ChannelTreeNode[] = []
  const lowerKeyword = keyword.toLowerCase()
  
  nodes.forEach(node => {
    const nodeCopy = { ...node }
    
    // 检查当前节点是否匹配
    const isCurrentMatch = node.label.toLowerCase().includes(lowerKeyword)
    
    // 递归过滤子节点
    let filteredChildren: ChannelTreeNode[] = []
    if (node.children) {
      filteredChildren = filterTreeData(node.children, keyword)
    }
    
    // 如果当前节点匹配或有匹配的子节点，则包含此节点
    if (isCurrentMatch || filteredChildren.length > 0) {
      nodeCopy.children = filteredChildren
      filtered.push(nodeCopy)
    }
  })
  
  return filtered
}

const handleCheck = (_data: any, checkedInfo: any) => {
  const checkedKeys = checkedInfo.checkedKeys
  const checkedNodes = checkedInfo.checkedNodes
  emit('check', checkedKeys, checkedNodes)
}

const handleNodeClick = (data: any) => {
  emit('node-click', data)
}

// 检查IP是否需要截断
const isIpTruncated = (ip: string) => {
  return ip.length > 15 // 假设最大显示15个字符
}

// 处理播放按钮点击
const handlePlayClick = (data: ChannelTreeNode) => {
  if (data.type === 'camera' && data.data?.originalData) {
    const device = data.data.originalData as Device
    
    // 通过nvrId从streamServers中找到对应的StreamServer
    const server = streamStore.streamServers.find(s => s.id === device.nvrId)
    
    if (!server) {
      console.error(`未找到nvrId为 ${device.nvrId} 的流媒体服务器`)
      // 可以显示错误提示
      return
    }
    
    // 验证流地址是否可以构建
    const testStreamUrl = buildStreamUrl(device, server, 'flvsub')
    if (!testStreamUrl) {
      console.error(`无法为设备 ${device.name} 构建流地址`)
      // 可以显示错误提示
      return
    }
    
    selectedCameraData.value = device
    selectedServerData.value = server
    streamPlayerVisible.value = true
    
    console.log('播放设备:', device.name)
    console.log('使用服务器:', server.name)
    console.log('构建的流地址:', testStreamUrl)
  }
}

// 关闭播放器
const handleStreamPlayerClose = () => {
  streamPlayerVisible.value = false
  selectedCameraData.value = null
  selectedServerData.value = null
}

// 将TreeNode转换为ChannelTreeNode
const convertToChannelTree = (nodes: any[]): ChannelTreeNode[] => {
  return nodes.map(node => {
    const channelNode: ChannelTreeNode = {
      id: `group_${node.id}`,
      label: node.name,
      type: 'group',
      parentId: node.parentId ? `group_${node.parentId}` : undefined,
      children: [],
      disabled: false,
      isLeaf: false,
      data: {
        originalData: node,
        checked: false
      }
    }

    // 初始化children数组
    channelNode.children = []

    // 递归处理子目录（文件夹排在前面）
    if (node.children && node.children.length > 0) {
      const childNodes = convertToChannelTree(node.children)
      channelNode.children.push(...childNodes)
    }

    // 添加设备作为子节点（设备排在后面）
    if (node.devices && node.devices.length > 0) {
      const deviceNodes = node.devices.map((device: any) => ({
        id: `camera_${device.id}`,
        label: device.name,
        type: 'camera' as const,
        parentId: `group_${node.id}`,
        disabled: false,
        isLeaf: true,
        data: {
          originalData: device,
          checked: false,
          status: device.status === 1 ? 'online' : 'offline',
          ip: device.ip,
          port: device.port
        }
      }))
      channelNode.children.push(...deviceNodes)
    }

    return channelNode
  })
}

// 加载数据
const loadData = async () => {
  try {
    loading.value = true
    const { treeData: rawTreeData } = await fetchCameraTree()
    const treeWithDevices = await loadDevicesForTree(rawTreeData)
    treeData.value = convertToChannelTree(treeWithDevices)
    
    // 应用搜索过滤
    applySearchFilter()
    
    // 默认展开第一层节点
    defaultExpandedKeys.value = filteredTreeData.value.map(node => node.id)
  } catch (error) {
    console.error('加载通道树数据失败:', error)
  } finally {
    loading.value = false
  }
}

// 应用搜索过滤
const applySearchFilter = () => {
  filteredTreeData.value = filterTreeData(treeData.value, props.searchKeyword)
}

// 高亮文本方法
const highlightText = (text: string, keyword: string): string => {
  if (!keyword.trim()) {
    return text
  }
  
  const regex = new RegExp(`(${keyword})`, 'gi')
  return text.replace(regex, '<span class="highlight">$1</span>')
}

// 监听props变化
watch(() => props.modelValue, (newValue) => {
  defaultCheckedKeys.value = newValue
}, { immediate: true })

// 监听搜索关键词变化
watch(() => props.searchKeyword, () => {
  applySearchFilter()
  // 搜索时自动展开所有匹配的节点
  if (props.searchKeyword.trim()) {
    const allKeys = getAllNodeKeys(filteredTreeData.value)
    defaultExpandedKeys.value = allKeys
  } else {
    // 清除搜索时，只展开第一层
    defaultExpandedKeys.value = filteredTreeData.value.map(node => node.id)
  }
})

// 生命周期
onMounted(() => {
  loadData()
})

// 暴露方法给父组件
defineExpose({
  expandAll,
  collapseAll,
  loadData,
  getCheckedKeys: () => treeRef.value?.getCheckedKeys(),
  getCheckedNodes: () => treeRef.value?.getCheckedNodes()
})
</script>

<style scoped>
.channel-tree-v2 {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;
}

.tree-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
}

.tree-title {
  font-weight: 600;
  color: #303133;
}

.tree-actions {
  display: flex;
  gap: 8px;
}

.channel-tree {
  width: 100%;
}

.tree-node {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 4px 0;
  min-height: 32px; /* 确保最小高度一致 */
}

.node-icon {
  margin-right: 8px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
}

.group-icon {
  color: #409eff;
}

.camera-icon {
  color: #67c23a;
}

.node-label {
  flex: 1;
  font-size: 14px;
  color: #606266;
  display: flex;
  align-items: center;
  height: 20px;
  line-height: 20px;
}

.node-info {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  max-width: 300px;
  height: 24px; /* 固定高度确保对齐 */
  min-width: 200px; /* 确保最小宽度，让所有内容有足够空间 */
}

.status-tag {
  font-size: 12px;
  flex-shrink: 0;
  width: 40px; /* 固定宽度，确保所有"在线"标签对齐 */
  height: 20px;
  line-height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.play-button {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 为没有播放按钮的情况添加占位空间 */
.play-button-placeholder {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
}

.ip-info {
  font-size: 12px;
  color: #909399;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex-shrink: 1;
  height: 20px;
  line-height: 20px;
  display: flex;
  align-items: center;
}

/* 滚动条样式 */
:deep(.el-tree-v2__virtual-list) {
  scrollbar-width: thin;
  scrollbar-color: #c1c1c1 #f1f1f1;
}

:deep(.el-tree-v2__virtual-list)::-webkit-scrollbar {
  width: 6px;
}

:deep(.el-tree-v2__virtual-list)::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

:deep(.el-tree-v2__virtual-list)::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

:deep(.el-tree-v2__virtual-list)::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* 搜索高亮样式 */
.highlight {
  background-color: #ffeb3b;
  color: #333;
  font-weight: bold;
  padding: 1px 2px;
  border-radius: 2px;
}
</style>
